home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / net_src.arc / fingcli.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  5.9 KB  |  282 lines

  1. /*
  2.  *
  3.  *    Finger support...
  4.  *
  5.  *    Finger client routines.  Written by Michael T. Horne - KA7AXD.
  6.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  7.  *    Permission granted for non-commercial use and copying, provided
  8.  *    that this notice is retained.
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "config.h"
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "timer.h"
  17. #include "internet.h"
  18. #include "icmp.h"
  19. #include "netuser.h"
  20. #include "tcp.h"
  21. #include "ftp.h"
  22. #include "telnet.h"
  23. #include "iface.h"
  24. #include "ax25.h"
  25. #include "lapb.h"
  26. #include "finger.h"
  27. #include "session.h"
  28. #include "nr4.h"
  29.  
  30. extern char    badhost[],
  31.         hostname[];
  32.  
  33. /*
  34.  *
  35.  *    Open up a socket to a remote (or the local) host on its finger port.
  36.  *
  37.  */
  38.  
  39. int
  40. dofinger(argc,argv)
  41. int    argc;
  42. char    *argv[];
  43. {
  44.     void        f_state(),
  45.             fingcli_rcv();
  46.     char        *inet_ntoa();
  47.     int32        resolve();
  48.     struct session    *s;
  49.     struct tcb    *tcb;
  50.     struct socket    lsocket,
  51.             fsocket;
  52.     struct finger    *finger,
  53.                     *alloc_finger();
  54.     char        *host;
  55.  
  56.     if (argc < 2) {
  57.         printf("usage: %s [user | user@host | @host]\n", argv[0]);
  58.         return(1);
  59.     }
  60.  
  61.     lsocket.address = ip_addr;
  62.     lsocket.port = lport++;
  63.  
  64. /*
  65.  *    Extract user/host information.  It can be of the form:
  66.  *    
  67.  *    finger user,            # finger local user
  68.  *    finger user@host,        # finger remote user
  69.  *    finger @host            # finger host (give system status)
  70.  *
  71.  */
  72.     if ((finger = alloc_finger()) == NULLFING)
  73.         return(1);
  74.  
  75.     if ((host = index(argv[1], '@')) == NULL) {
  76.         fsocket.address = ip_addr;    /* no host, use local */
  77.         if ((finger->user = malloc(strlen(argv[1]) + 3)) == NULL) {
  78.             free_finger(finger);
  79.             return(1);
  80.         }
  81.         strcpy(finger->user, argv[1]);
  82.         strcat(finger->user, "\015\012");
  83.     }
  84.     else {
  85.         *host++ = '\0';        /* null terminate user name */
  86.         if (*host == '\0') {    /* must specify host */
  87.             printf("%s: no host specified\n", argv[0]);
  88.             printf("usage: %s [user | user@host | @host]\n",
  89.                 argv[0]);
  90.             free_finger(finger);
  91.             return(1);
  92.         }
  93.         if ((fsocket.address = resolve(host)) == 0) {
  94.             printf("%s: ", argv[0]);
  95.             printf(badhost, host); 
  96.             free_finger(finger);
  97.             return(1);
  98.         }
  99.         if ((finger->user = malloc(strlen(argv[1])+3))==NULL) {
  100.             free_finger(finger);
  101.             return 1;
  102.         }
  103.         strcpy(finger->user, argv[1]);
  104.         strcat(finger->user, "\015\012");
  105.     }
  106.     
  107.     fsocket.port = FINGER_PORT;        /* use finger wnp */
  108.  
  109.     /* Allocate a session descriptor */
  110.     if ((s = newsession()) == NULLSESSION){
  111.         printf("Too many sessions\n");
  112.         free_finger(finger);
  113.         return 1;
  114.     }
  115.     current = s;
  116.     s->cb.finger = finger;
  117.     finger->session = s;
  118.  
  119.     if (!host)                /* if no host specified */
  120.         host = hostname;        /* use local host name */
  121.     if ((s->name = malloc(strlen(host)+1)) != NULLCHAR)
  122.         strcpy(s->name, host);
  123.  
  124.     s->type = FINGER;
  125.     s->parse = (int (*)()) NULL;
  126.  
  127.     tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  128.      fingcli_rcv, (void (*)()) 0, f_state, 0, (int *) finger);
  129.  
  130.     finger->tcb = tcb;
  131.     tcb->user = (char *)finger;
  132.     go();
  133.     return 0;
  134. }
  135.  
  136. /*
  137.  *    Allocate a finger structure for the new session
  138.  */
  139. struct finger *
  140. alloc_finger()
  141. {
  142.     struct finger *tmp;
  143.  
  144.     if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
  145.         return(NULLFING);
  146.     tmp->session = NULLSESSION;
  147.     tmp->user = (char *) NULL;
  148.     return(tmp);
  149. }
  150.  
  151. /*
  152.  *    Free a finger structure
  153.  */
  154. int
  155. free_finger(finger)
  156. struct finger *finger;
  157. {
  158.     if (finger != NULLFING) {
  159.         if (finger->session != NULLSESSION)
  160.             freesession(finger->session);
  161.         if (finger->user != (char *) NULL)
  162.             free(finger->user);
  163.         free(finger);
  164.     }
  165.     return 0;
  166. }
  167.  
  168. /* Finger receiver upcall routine */
  169. void
  170. fingcli_rcv(tcb, cnt)
  171. register struct tcb    *tcb;
  172. int16            cnt;
  173. {
  174.     struct mbuf    *bp;
  175.     char        *buf;
  176.  
  177.     /* Make sure it's a valid finger session */
  178.     if ((struct finger *) tcb->user == NULLFING) {
  179.         return;
  180.     }
  181.  
  182.     /* Hold output if we're not the current session */
  183.     if (mode != CONV_MODE || current == NULLSESSION
  184.         || current->type != FINGER)
  185.         return;
  186.  
  187.     /*
  188.      *    We process the incoming data stream and make sure it
  189.      *    meets our requirments.  A check is made for control-Zs
  190.      *    since these characters lock up DoubleDos when sent to
  191.      *    the console (don't you just love it...).
  192.      */
  193.  
  194.     if (recv_tcp(tcb, &bp, cnt) > 0)
  195.         while (bp != NULLBUF) {
  196.             buf = bp->data;
  197.             while(bp->cnt--) {
  198.                 switch(*buf) {
  199.                     case '\012':    /* ignore LF */
  200.                     case '\032':    /* NO ^Z's! */
  201.                         break;
  202.                     case '\015':
  203.                         fputc('\015', stdout);
  204.                         fputc('\012', stdout);
  205.                         break;
  206.                     default:
  207.                         fputc(*buf, stdout);
  208.                         break;
  209.                 }
  210.                 buf++;
  211.             }
  212.             bp = free_mbuf(bp);
  213.         }
  214.     fflush(stdout);
  215. }
  216.  
  217. /* State change upcall routine */
  218. void
  219. f_state(tcb,old,new)
  220. register struct tcb    *tcb;
  221. char            old,        /* old state */
  222.             new;        /* new state */
  223. {
  224.     struct finger    *finger;
  225.     char        notify = 0;
  226.     extern char    *tcpstates[];
  227.     extern char    *reasons[];
  228.     extern char    *unreach[];
  229.     extern char    *exceed[];
  230.     struct mbuf    *bp;
  231.  
  232.     finger = (struct finger *)tcb->user;
  233.  
  234.     if(current != NULLSESSION && current->type == FINGER)
  235.         notify = 1;
  236.  
  237.     switch(new){
  238.  
  239.     case CLOSE_WAIT:
  240.         if(notify)
  241.             printf("%s\n",tcpstates[new]);
  242.         close_tcp(tcb);
  243.         break;
  244.  
  245.     case CLOSED:    /* finish up */
  246.         if(notify) {
  247.             printf("%s (%s", tcpstates[new], reasons[tcb->reason]);
  248.             if (tcb->reason == NETWORK){
  249.                 switch(tcb->type){
  250.                 case DEST_UNREACH:
  251.                     printf(": %s unreachable",unreach[tcb->code]);
  252.                     break;
  253.                 case TIME_EXCEED:
  254.                     printf(": %s time exceeded",exceed[tcb->code]);
  255.                     break;
  256.                 }
  257.             }
  258.             printf(")\n");
  259.             cmdmode();
  260.         }
  261.         if(finger != NULLFING)
  262.             free_finger(finger);
  263.         del_tcp(tcb);
  264.         break;
  265.     case ESTABLISHED:
  266.         if (notify) {
  267.             printf("%s\n",tcpstates[new]);
  268.         }
  269.         printf("[%s]\n", current->name);
  270.         bp = qdata(finger->user, (int16) strlen(finger->user));
  271.         send_tcp(tcb, bp);
  272.         break;
  273.         
  274.     default:
  275.         if(notify)
  276.             printf("%s\n",tcpstates[new]);
  277.         break;
  278.     }
  279.     fflush(stdout);
  280. }
  281.  
  282.